package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.domain.Lecture;
import com.example.domain.LectureRegistration;
import com.example.domain.Room;
import com.example.domain.User;
import com.example.dto.LectureAddDTO;
import com.example.dto.LectureUpdateDTO;
import com.example.exception.BusinessException;
import com.example.mapper.LectureMapper;
import com.example.mapper.LectureRegistrationMapper;
import com.example.mapper.LibraryMapper;
import com.example.mapper.RoomMapper;
import com.example.mapper.UserMapper;
import com.example.service.LectureService;
import com.example.service.OperationLogService;
import com.example.util.Result;
import com.example.util.DistributedLock;
import com.example.vo.LectureVO;
import com.example.domain.Library;
import com.example.mapper.LibraryMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.text.SimpleDateFormat;

/**
* @author HP
* @description 针对表【lecture】的数据库操作Service实现
* @createDate 2025-08-18 19:33:01
*/

@Slf4j
@Service
public class LectureServiceImpl extends ServiceImpl<LectureMapper, Lecture>
    implements LectureService {

    @Resource
    private LectureMapper lectureMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private LectureRegistrationMapper lectureRegistrationMapper;

    @Resource
    private OperationLogService operationLogService;
    @Autowired
    private RoomMapper roomMapper;

    @Resource
    private LibraryMapper libraryMapper;

    @Resource
    private DistributedLock distributedLock;

    @Override
    public Result addLecture(LectureAddDTO lectureAddDTO) {
        // 验证讲座信息
        if (lectureAddDTO == null || lectureAddDTO.getTitle() == null || lectureAddDTO.getTitle().trim().isEmpty()) {
            throw new BusinessException("讲座标题不能为空");
        }
        if (lectureAddDTO.getLecturer() == null || lectureAddDTO.getLecturer().trim().isEmpty()) {
            throw new BusinessException("主讲人不能为空");
        }
        if (lectureAddDTO.getStartTime() == null || lectureAddDTO.getEndTime() == null) {
            throw new BusinessException("讲座时间不能为空");
        }
        if (lectureAddDTO.getStartTime().after(lectureAddDTO.getEndTime())) {
            throw new BusinessException("讲座开始时间不能晚于结束时间");
        }
        // 验证人数限制
        if (lectureAddDTO.getParticipantLimit() != null && lectureAddDTO.getParticipantLimit() < 0) {
            throw new BusinessException("参与人数限制不能为负数");
        }

        // 验证讲座是否已存在
        Lecture existingLecture = lectureMapper.selectOne(new QueryWrapper<Lecture>().eq("title", lectureAddDTO.getTitle()));
        if (existingLecture != null) {
            throw new BusinessException("讲座标题已存在");
        }

        // 验证讲座地点是否存在
        if (lectureAddDTO.getClassroomId() == null) {
            throw new BusinessException("讲座地点不能为空");
        }
        Room room = roomMapper.selectById(lectureAddDTO.getClassroomId());
        if (room == null) {
            throw new BusinessException("讲座地点不存在");
        }
        // 创建讲座
        Lecture lecture = new Lecture();
        BeanUtils.copyProperties(lectureAddDTO, lecture);
        // 讲座只能创建今天以后的时间
        Date now = new Date();
        Date startTime = lecture.getStartTime();

        if (startTime.before(now)) {
            throw new BusinessException("讲座只能创建今天以后的时间");
        }
        int insert = lectureMapper.insert(lecture);

        if (insert <= 0) {
            throw new BusinessException("添加讲座失败");
        }

//        // 记录操作日志
//        operationLogService.recordLog(
//            null, // 管理员ID（需要从上下文获取）
//            lecture.getId(),
//            4, // 实体类型：4-讲座
//            String.format("管理员添加讲座：%s，主讲人：%s，时间：%s",
//                         lecture.getTitle(), lecture.getLecturer(), lecture.getStartTime())
//        );
        
        return Result.success();
    }

    @Override
    public Result updateLecture(LectureUpdateDTO lectureUpdateDTO) {
        if (lectureUpdateDTO == null || lectureUpdateDTO.getId() == null) {
            throw new BusinessException("讲座ID不能为空");
        }

        // 检查讲座是否存在
        Lecture existingLecture = lectureMapper.selectById(lectureUpdateDTO.getId());
        if (existingLecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 验证更新信息
        if (lectureUpdateDTO.getTitle() != null && lectureUpdateDTO.getTitle().trim().isEmpty()) {
            throw new BusinessException("讲座标题不能为空");
        }
        if (lectureUpdateDTO.getLecturer() != null && lectureUpdateDTO.getLecturer().trim().isEmpty()) {
            throw new BusinessException("主讲人不能为空");
        }
        if (lectureUpdateDTO.getStartTime() != null && lectureUpdateDTO.getEndTime() != null && lectureUpdateDTO.getStartTime().after(lectureUpdateDTO.getEndTime())) {
            throw new BusinessException("讲座开始时间不能晚于结束时间");
        }

        // 验证人数限制（如果有更新）
        if (lectureUpdateDTO.getParticipantLimit() != null) {
            if (lectureUpdateDTO.getParticipantLimit() < 0) {
                throw new BusinessException("参与人数限制不能为负数");
            }
            
            // 检查新的人数限制是否会小于当前已报名人数
            QueryWrapper<LectureRegistration> countWrapper = new QueryWrapper<>();
            countWrapper.eq("lecture_id", lectureUpdateDTO.getId());
            countWrapper.ne("registration_status", 2); // 排除已取消的
            
            long currentCount = lectureRegistrationMapper.selectCount(countWrapper);
            if (lectureUpdateDTO.getParticipantLimit() > 0 && currentCount > lectureUpdateDTO.getParticipantLimit()) {
                throw new BusinessException(String.format("新的人数限制（%d人）不能少于已报名人数（%d人）", 
                                                      lectureUpdateDTO.getParticipantLimit(), currentCount));
            }
        }
        // 验证讲座地点是否存在
        if (lectureUpdateDTO.getClassroomId() != null) {
            Room room = roomMapper.selectById(lectureUpdateDTO.getClassroomId());
            if (room == null) {
                throw new BusinessException("讲座地点不存在");
            }
            // 该房间是否有讲座
            QueryWrapper<Lecture> roomWrapper = new QueryWrapper<>();
            roomWrapper.eq("classroom_id", lectureUpdateDTO.getClassroomId());
            List<Lecture> roomLectures = lectureMapper.selectList(roomWrapper);
            if (!roomLectures.isEmpty()) {
                // 判断时间是否冲突
                for (Lecture roomLecture : roomLectures) {
                    if (roomLecture.getId().equals(lectureUpdateDTO.getId())) {
                        continue; // 排除自己
                    }
                    if (roomLecture.getStartTime().before(lectureUpdateDTO.getEndTime()) && roomLecture.getEndTime().after(lectureUpdateDTO.getStartTime())) {
                        throw new BusinessException("该房间时间冲突，请选择其他时间");
                    }
                }
            }
        }
        Lecture lecture = new Lecture();
        BeanUtils.copyProperties(lectureUpdateDTO, lecture);
        int update = lectureMapper.updateById(lecture);
        if (update <= 0) {
            throw new BusinessException("更新讲座失败");
        }
        
        // 记录操作日志
        StringBuilder updateFields = new StringBuilder();
        if (lectureUpdateDTO.getTitle() != null) {
            updateFields.append("标题:").append(lectureUpdateDTO.getTitle()).append("; ");
        }
        if (lectureUpdateDTO.getLecturer() != null) {
            updateFields.append("主讲人:").append(lectureUpdateDTO.getLecturer()).append("; ");
        }
        if (lectureUpdateDTO.getStartTime() != null) {
            updateFields.append("开始时间:").append(lectureUpdateDTO.getStartTime()).append("; ");
        }
        if (lectureUpdateDTO.getParticipantLimit() != null) {
            updateFields.append("人数限制:").append(lectureUpdateDTO.getParticipantLimit()).append("; ");
        }
        
        operationLogService.recordLog(
            null, // 管理员ID（需要从上下文获取）
            lectureUpdateDTO.getId(),
            4, // 实体类型：4-讲座
            String.format("管理员修改讲座：%s，修改内容：%s", 
                         existingLecture.getTitle(), updateFields.toString())
        );
        
        return Result.success();
    }

    @Override
    public Result deleteLecture(Long id) {
        if (id == null) {
            throw new BusinessException("讲座ID不能为空");
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(id);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 检查是否有用户预约
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lecture_id", id);
        List<LectureRegistration> registrations = lectureRegistrationMapper.selectList(queryWrapper);
        if (registrations != null && !registrations.isEmpty()) {
            throw new BusinessException("该讲座已有用户预约，无法删除");
        }

        int delete = lectureMapper.deleteById(id);
        if (delete <= 0) {
            throw new BusinessException("删除讲座失败");
        }
        
        // 记录操作日志
        operationLogService.recordLog(
            null, // 管理员ID（需要从上下文获取）
            id,
            4, // 实体类型：4-讲座
            String.format("管理员删除讲座：%s，主讲人：%s", 
                         lecture.getTitle(), lecture.getLecturer())
        );
        
        return Result.success();
    }

    @Override
    public Lecture getLectureById(Long id) {
        if (id == null) {
            throw new BusinessException("讲座ID不能为空");
        }

        Lecture lecture = lectureMapper.selectById(id);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }
        return lecture;
    }

    @Override
    public List<Lecture> listAllLectures() {
        // 过滤已结束的讲座（状态为2）
        QueryWrapper<Lecture> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("lecture_status", 2); // 排除已结束的讲座
        List<Lecture> lectures = lectureMapper.selectList(queryWrapper);
        return lectures;
    }

    @Override
    public boolean reserveLecture(Long userId, Long lectureId) {
        if (userId == null || lectureId == null) {
            throw new BusinessException("用户ID和讲座ID不能为空");
        }

        // 使用分布式锁防止并发报名冲突
        try {
            return distributedLock.executeWithLectureLock(lectureId, 10, () -> {
                return doReserveLecture(userId, lectureId);
            });
        } catch (Exception e) {
            if (e instanceof BusinessException) {
                throw (BusinessException) e;
            }
            throw new BusinessException("报名失败：" + e.getMessage());
        }
    }

    /**
     * 执行讲座报名的核心逻辑
     * @param userId 用户ID
     * @param lectureId 讲座ID
     * @return 是否报名成功
     */
    private boolean doReserveLecture(Long userId, Long lectureId) {
        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 检查讲座状态
        if (lecture.getLectureStatus() == 3) { // 已取消
            throw new BusinessException("该讲座已取消，无法报名");
        }
        if (lecture.getLectureStatus() == 2) { // 已结束
            throw new BusinessException("该讲座已结束，无法报名");
        }

        // 检查讲座是否已开始
        Date now = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
        if (lecture.getStartTime().before(now)) {
            throw new BusinessException("该讲座已开始，无法报名");
        }

        // 检查用户权限（如果用户被禁用报名功能）
        if (user.getRegistrationDisabled() == 1) {
            throw new BusinessException("您的报名功能已被禁用，请联系管理员");
        }

        // 检查用户是否已预约
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("lecture_id", lectureId);
        LectureRegistration existingRegistration = lectureRegistrationMapper.selectOne(queryWrapper);
        if (existingRegistration != null) {
            if (existingRegistration.getRegistrationStatus() == 2) {
                throw new BusinessException("您已取消该讲座报名，如需重新报名请联系管理员");
            }
            throw new BusinessException("您已预约该讲座");
        }

        // =============== 关键并发控制区域 ===============
        // 检查人数限制（核心功能 - 必须在锁内执行）
        if (lecture.getParticipantLimit() != null && lecture.getParticipantLimit() > 0) {
            QueryWrapper<LectureRegistration> countWrapper = new QueryWrapper<>();
            countWrapper.eq("lecture_id", lectureId);
            countWrapper.ne("registration_status", 2); // 排除已取消的报名
            
            long currentCount = lectureRegistrationMapper.selectCount(countWrapper);
            if (currentCount >= lecture.getParticipantLimit()) {
                throw new BusinessException(String.format("该讲座报名人数已满，当前报名：%d人，限制：%d人", 
                                                      currentCount, lecture.getParticipantLimit()));
            }
        }

        // 创建预约记录
        LectureRegistration registration = new LectureRegistration();
        registration.setUserId(userId);
        registration.setLectureId(lectureId);
        registration.setRegisteredTime(new Date());
        registration.setRegistrationStatus(0); // 设置初始状态为待签到

        int insert = lectureRegistrationMapper.insert(registration);
        if (insert <= 0) {
            throw new BusinessException("预约失败");
        }
        // =============== 关键并发控制区域结束 ===============
        
        // 记录操作日志
        operationLogService.recordLog(
            userId,
            lectureId,
            4, // 实体类型：4-讲座
            String.format("用户报名讲座：%s", lecture.getTitle())
        );

        return true;
    }

    @Override
    public List<User> getLectureReservations(Long lectureId) {
        if (lectureId == null) {
            throw new BusinessException("讲座ID不能为空");
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 查询预约记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lecture_id", lectureId);
        List<LectureRegistration> registrations = lectureRegistrationMapper.selectList(queryWrapper);

        // 根据预约记录查询用户
        List<User> users = registrations.stream()
                .map(registration -> userMapper.selectById(registration.getUserId()))
                .filter(user -> user != null)
                .toList();

        return users;
    }

    @Override
    public Map<String, Object> getRegistrationStatistics(Long lectureId) {
        if (lectureId == null) {
            throw new BusinessException("讲座ID不能为空");
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 统计报名和签到情况
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lecture_id", lectureId);
        
        List<LectureRegistration> allRegistrations = lectureRegistrationMapper.selectList(queryWrapper);
        
        long totalRegistrations = allRegistrations.stream()
                .filter(r -> r.getRegistrationStatus() != 2)
                .count(); // 总报名数（排除已取消）
        
        long checkedIn = allRegistrations.stream()
                .filter(r -> r.getRegistrationStatus() == 1)
                .count(); // 已签到数
        
        long cancelled = allRegistrations.stream()
                .filter(r -> r.getRegistrationStatus() == 2)
                .count(); // 已取消数
        
        long notCheckedIn = totalRegistrations - checkedIn; // 未签到数

        Map<String, Object> statistics = new HashMap<>();
        statistics.put("lectureInfo", lecture);
        statistics.put("totalRegistrations", totalRegistrations);
        statistics.put("checkedIn", checkedIn);
        statistics.put("notCheckedIn", notCheckedIn);
        statistics.put("cancelled", cancelled);
        statistics.put("checkInRate", totalRegistrations > 0 ? 
                      String.format("%.1f%%", (double) checkedIn / totalRegistrations * 100) : "0%");
        statistics.put("participantLimit", lecture.getParticipantLimit());
        statistics.put("availableSlots", lecture.getParticipantLimit() != null ? 
                                       Math.max(0, lecture.getParticipantLimit() - totalRegistrations) : "无限制");
        statistics.put("isFull", isLectureFull(lectureId));

        return statistics;
    }

    @Override
    public boolean isLectureFull(Long lectureId) {
        if (lectureId == null) {
            throw new BusinessException("讲座ID不能为空");
        }

        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 如果没有设置人数限制，返回 false
        if (lecture.getParticipantLimit() == null || lecture.getParticipantLimit() <= 0) {
            return false;
        }

        // 统计当前报名人数（排除已取消的）
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lecture_id", lectureId);
        queryWrapper.ne("registration_status", 2);
        
        long currentCount = lectureRegistrationMapper.selectCount(queryWrapper);
        
        return currentCount >= lecture.getParticipantLimit();
    }

    @Override
    public int getRemainingSlots(Long lectureId) {
        if (lectureId == null) {
            throw new BusinessException("讲座ID不能为空");
        }

        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 如果没有设置人数限制，返回 -1 表示无限制
        if (lecture.getParticipantLimit() == null || lecture.getParticipantLimit() <= 0) {
            return -1;
        }

        // 统计当前报名人数（排除已取消的）
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lecture_id", lectureId);
        queryWrapper.ne("registration_status", 2);
        
        long currentCount = lectureRegistrationMapper.selectCount(queryWrapper);
        
        return Math.max(0, (int)(lecture.getParticipantLimit() - currentCount));
    }

    @Override
    public boolean cancelRegistration(Long userId, Long lectureId) {
        if (userId == null || lectureId == null) {
            throw new BusinessException("用户ID和讲座ID不能为空");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 检查报名记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("lecture_id", lectureId);
        
        LectureRegistration registration = lectureRegistrationMapper.selectOne(queryWrapper);
        if (registration == null) {
            throw new BusinessException("未找到报名记录");
        }

        // 检查报名状态
        if (registration.getRegistrationStatus() == 2) {
            throw new BusinessException("该报名已取消");
        }

        if (registration.getRegistrationStatus() == 1) {
            throw new BusinessException("您已签到，无法取消报名");
        }

        // 检查取消时间限制（讲座开始前2小时内不允许取消）
        Date now = new Date();
        long twoHours = 2 * 60 * 60 * 1000; // 2小时的毫秒数
        Date cancelDeadline = new Date(lecture.getStartTime().getTime() - twoHours);
        
        if (now.after(cancelDeadline)) {
            throw new BusinessException("讲座开始前2小时内不允许取消报名");
        }

        // 执行取消
        registration.setRegistrationStatus(2); // 已取消

        int update = lectureRegistrationMapper.updateById(registration);
        if (update <= 0) {
            throw new BusinessException("取消报名失败");
        }

        // 记录操作日志
        operationLogService.recordLog(
            userId,
            lectureId,
            4, // 实体类型：4-讲座
            String.format("用户取消讲座报名：%s", lecture.getTitle())
        );

        return true;
    }

    @Override
    public boolean adminCancelRegistration(Long userId, Long lectureId, Long operatorId, String reason) {
        if (userId == null || lectureId == null || operatorId == null) {
            throw new BusinessException("用户ID、讲座ID和操作人ID不能为空");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查操作人是否存在且有权限
        User operator = userMapper.selectById(operatorId);
        if (operator == null) {
            throw new BusinessException("操作人不存在");
        }
        if (operator.getRole() == 1) {
            throw new BusinessException("无权限执行此操作");
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 检查报名记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("lecture_id", lectureId);
        
        LectureRegistration registration = lectureRegistrationMapper.selectOne(queryWrapper);
        if (registration == null) {
            throw new BusinessException("未找到报名记录");
        }

        // 检查报名状态
        if (registration.getRegistrationStatus() == 2) {
            throw new BusinessException("该报名已取消");
        }

        // 管理员可以强制取消，无时间限制
        registration.setRegistrationStatus(2); // 已取消

        int update = lectureRegistrationMapper.updateById(registration);
        if (update <= 0) {
            throw new BusinessException("取消报名失败");
        }

        // 记录操作日志
        String logMessage = String.format("管理员[%s]取消用户[%s]的讲座报名：%s", 
                                          operator.getUsername(), user.getUsername(), lecture.getTitle());
        if (reason != null && !reason.trim().isEmpty()) {
            logMessage += "，原因：" + reason;
        }
        
        operationLogService.recordLog(
            operatorId,
            lectureId,
            4, // 实体类型：4-讲座
            logMessage
        );

        return true;
    }

    @Override
    public List<Map<String, Object>> getUserRegistrations(Long userId) {
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 查询用户的所有报名记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.orderByDesc("registered_time");
        
        List<LectureRegistration> registrations = lectureRegistrationMapper.selectList(queryWrapper);
        
        // 组装返回数据
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<Map<String, Object>> result = registrations.stream()
                .map(registration -> {
                    Map<String, Object> item = new HashMap<>();
                    
                    // 获取讲座信息
                    Lecture lecture = lectureMapper.selectById(registration.getLectureId());
                    
                    item.put("registrationId", registration.getId());
                    item.put("lectureId", registration.getLectureId());
                    item.put("lectureTitle", lecture != null ? lecture.getTitle() : "讲座已删除");
                    item.put("lecturer", lecture != null ? lecture.getLecturer() : "");
                    
                    // 格式化时间
                    item.put("startTime", lecture != null && lecture.getStartTime() != null ? sdf.format(lecture.getStartTime()) : null);
                    item.put("endTime", lecture != null && lecture.getEndTime() != null ? sdf.format(lecture.getEndTime()) : null);
                    item.put("registeredTime", registration.getRegisteredTime() != null ? sdf.format(registration.getRegisteredTime()) : null);
                    item.put("signTime", registration.getSignTime() != null ? sdf.format(registration.getSignTime()) : null);
                    
                    // 报名状态文本
                    String statusText;
                    switch (registration.getRegistrationStatus()) {
                        case 0:
                            statusText = "待签到";
                            break;
                        case 1:
                            statusText = "已签到";
                            break;
                        case 2:
                            statusText = "已取消";
                            break;
                        default:
                            statusText = "未知状态";
                    }
                    item.put("registrationStatus", registration.getRegistrationStatus());
                    item.put("registrationStatusText", statusText);
                    
                    // 判断是否可以取消
                    boolean canCancel = false;
                    if (lecture != null && registration.getRegistrationStatus() == 0) {
                        Date now = new Date();
                        long twoHours = 2 * 60 * 60 * 1000;
                        Date cancelDeadline = new Date(lecture.getStartTime().getTime() - twoHours);
                        canCancel = now.before(cancelDeadline);
                    }
                    item.put("canCancel", canCancel);
                    
                    return item;
                })
                .toList();
        
        return result;
    }

    @Override
    public boolean hasUserRegistered(Long userId, Long lectureId) {
        if (userId == null || lectureId == null) {
            throw new BusinessException("用户ID和讲座ID不能为空");
        }

        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("lecture_id", lectureId);
        queryWrapper.ne("registration_status", 2); // 排除已取消的
        
        long count = lectureRegistrationMapper.selectCount(queryWrapper);
        return count > 0;
    }

    @Override
    public Map<String, Object> getUserRegistrationStatus(Long userId, Long lectureId) {
        if (userId == null || lectureId == null) {
            throw new BusinessException("用户ID和讲座ID不能为空");
        }

        // 检查用户和讲座是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 查询报名记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("lecture_id", lectureId);
        
        LectureRegistration registration = lectureRegistrationMapper.selectOne(queryWrapper);
        
        Map<String, Object> status = new HashMap<>();
        status.put("userId", userId);
        status.put("lectureId", lectureId);
        status.put("lectureTitle", lecture.getTitle());
        status.put("hasRegistered", registration != null && registration.getRegistrationStatus() != 2);
        
        if (registration != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            
            status.put("registrationId", registration.getId());
            status.put("registeredTime", registration.getRegisteredTime() != null ? sdf.format(registration.getRegisteredTime()) : null);
            status.put("signTime", registration.getSignTime() != null ? sdf.format(registration.getSignTime()) : null);
            status.put("registrationStatus", registration.getRegistrationStatus());
            
            // 状态文本
            String statusText;
            switch (registration.getRegistrationStatus()) {
                case 0:
                    statusText = "待签到";
                    break;
                case 1:
                    statusText = "已签到";
                    break;
                case 2:
                    statusText = "已取消";
                    break;
                default:
                    statusText = "未知状态";
            }
            status.put("registrationStatusText", statusText);
            
            // 判断是否可以取消
            boolean canCancel = false;
            if (registration.getRegistrationStatus() == 0) {
                Date now = new Date();
                long twoHours = 2 * 60 * 60 * 1000;
                Date cancelDeadline = new Date(lecture.getStartTime().getTime() - twoHours);
                canCancel = now.before(cancelDeadline);
            }
            status.put("canCancel", canCancel);
        } else {
            status.put("registrationId", null);
            status.put("registeredTime", null);
            status.put("signTime", null);
            status.put("registrationStatus", null);
            status.put("registrationStatusText", "未报名");
            status.put("canCancel", false);
        }
        
        return status;
    }

    // ==================== 签到管理功能实现 ====================

    @Override
    public boolean checkInLecture(Long userId, Long lectureId) {
        if (userId == null || lectureId == null) {
            throw new BusinessException("用户ID和讲座ID不能为空");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 检查讲座状态
        if (lecture.getLectureStatus() == 3) {
            throw new BusinessException("该讲座已取消，无法签到");
        }
        if (lecture.getLectureStatus() == 2) {
            throw new BusinessException("该讲座已结束，无法签到");
        }

        // 检查签到时间窗口（讲座开始前30分钟到讲座结束后15分钟）
        Date now = new Date();
        long thirtyMinutes = 30 * 60 * 1000; // 30分钟的毫秒数
        long fifteenMinutes = 15 * 60 * 1000; // 15分钟的毫秒数
        
        Date checkInStartTime = new Date(lecture.getStartTime().getTime() - thirtyMinutes);
        Date checkInEndTime = new Date(lecture.getEndTime().getTime() + fifteenMinutes);
        
        if (now.before(checkInStartTime)) {
            throw new BusinessException("签到时间未到，请在讲座开始前30分钟内签到");
        }
        if (now.after(checkInEndTime)) {
            throw new BusinessException("签到时间已过，请在讲座结束后15分钟内完成签到");
        }

        // 查询报名记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("lecture_id", lectureId);
        
        LectureRegistration registration = lectureRegistrationMapper.selectOne(queryWrapper);
        if (registration == null) {
            throw new BusinessException("未找到报名记录，请先报名再签到");
        }

        // 检查报名状态
        if (registration.getRegistrationStatus() == 2) {
            throw new BusinessException("报名已取消，无法签到");
        }
        if (registration.getRegistrationStatus() == 1) {
            throw new BusinessException("您已签到，无需重复签到");
        }

        // 执行签到
        registration.setRegistrationStatus(1); // 设置为已签到
        registration.setSignTime(now); // 记录签到时间

        int update = lectureRegistrationMapper.updateById(registration);
        if (update <= 0) {
            throw new BusinessException("签到失败");
        }

        // 记录操作日志
        operationLogService.recordLog(
            userId,
            lectureId,
            4, // 实体类型：4-讲座
            String.format("用户签到讲座：%s", lecture.getTitle())
        );

        return true;
    }

    @Override
    public boolean checkInLectureByRegistrationId(Long userId, Long registrationId) {
        if (userId == null || registrationId == null) {
            throw new BusinessException("用户ID和报名记录ID不能为空");
        }

        // 查询报名记录
        LectureRegistration registration = lectureRegistrationMapper.selectById(registrationId);
        if (registration == null) {
            throw new BusinessException("报名记录不存在");
        }

        // 验证是否为当前用户的报名记录
        if (!registration.getUserId().equals(userId)) {
            throw new BusinessException("无权限操作该报名记录");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(registration.getLectureId());
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 检查讲座状态
        if (lecture.getLectureStatus() == 3) {
            throw new BusinessException("该讲座已取消，无法签到");
        }
        if (lecture.getLectureStatus() == 2) {
            throw new BusinessException("该讲座已结束，无法签到");
        }

        // 检查签到时间窗口（讲座开始前30分钟到讲座结束后15分钟）
        Date now = new Date();
        long thirtyMinutes = 30 * 60 * 1000; // 30分钟的毫秒数
        long fifteenMinutes = 15 * 60 * 1000; // 15分钟的毫秒数
        
        Date checkInStartTime = new Date(lecture.getStartTime().getTime() - thirtyMinutes);
        Date checkInEndTime = new Date(lecture.getEndTime().getTime() + fifteenMinutes);
        
        if (now.before(checkInStartTime)) {
            throw new BusinessException("签到时间未到，请在讲座开始前30分钟内签到");
        }
        if (now.after(checkInEndTime)) {
            throw new BusinessException("签到时间已过，请在讲座结束后15分钟内完成签到");
        }

        // 检查报名状态
        if (registration.getRegistrationStatus() == 2) {
            throw new BusinessException("报名已取消，无法签到");
        }
        if (registration.getRegistrationStatus() == 1) {
            throw new BusinessException("您已签到，无需重复签到");
        }

        // 执行签到
        registration.setRegistrationStatus(1); // 设置为已签到
        registration.setSignTime(now); // 记录签到时间

        int update = lectureRegistrationMapper.updateById(registration);
        if (update <= 0) {
            throw new BusinessException("签到失败");
        }

        // 记录操作日志
        operationLogService.recordLog(
            userId,
            registration.getLectureId(),
            4, // 实体类型：4-讲座
            String.format("用户通过报名记录ID[%d]签到讲座：%s", registrationId, lecture.getTitle())
        );

        return true;
    }

    @Override
    public boolean adminCheckInLecture(Long userId, Long lectureId, Long operatorId) {
        if (userId == null || lectureId == null || operatorId == null) {
            throw new BusinessException("用户ID、讲座ID和操作人ID不能为空");
        }

        // 检查操作人是否是管理员
        User operator = userMapper.selectById(operatorId);
        if (operator == null) {
            throw new BusinessException("操作人不存在");
        }
        if (operator.getRole() == null || operator.getRole() > 2) { // 1:超级管理员 2:管理员
            throw new BusinessException("无权限执行此操作");
        }

        // 检查目标用户
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("目标用户不存在");
        }

        // 检查讲座
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 管理员代替签到无时间限制，但需要检查讲座状态
        if (lecture.getLectureStatus() == 3) {
            throw new BusinessException("该讲座已取消，无法签到");
        }

        // 查询报名记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("lecture_id", lectureId);
        
        LectureRegistration registration = lectureRegistrationMapper.selectOne(queryWrapper);
        if (registration == null) {
            throw new BusinessException("未找到报名记录");
        }

        if (registration.getRegistrationStatus() == 2) {
            throw new BusinessException("报名已取消，无法签到");
        }
        if (registration.getRegistrationStatus() == 1) {
            throw new BusinessException("用户已签到，无需重复操作");
        }

        // 执行签到
        registration.setRegistrationStatus(1);
        registration.setSignTime(new Date());

        int update = lectureRegistrationMapper.updateById(registration);
        if (update <= 0) {
            throw new BusinessException("签到失败");
        }

        // 记录操作日志
        operationLogService.recordLog(
            operatorId,
            lectureId,
            4, // 实体类型：4-讲座
            String.format("管理员[%s]代替用户[%s]签到讲座：%s",
                         operator.getUsername(), user.getUsername(), lecture.getTitle())
        );

        return true;
    }

    @Override
    public Map<String, Object> batchCheckIn(Long lectureId, List<Long> userIds, Long operatorId) {
        if (lectureId == null || userIds == null || userIds.isEmpty() || operatorId == null) {
            throw new BusinessException("参数不能为空");
        }

        // 检查操作人权限
        User operator = userMapper.selectById(operatorId);
        if (operator == null || operator.getRole() == null || operator.getRole() > 2) {
            throw new BusinessException("无权限执行批量签到操作");
        }

        // 检查讲座
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        List<String> successList = new ArrayList<>();
        List<Map<String, Object>> failureList = new ArrayList<>();
        int successCount = 0;

        for (Long userId : userIds) {
            try {
                // 检查用户
                User user = userMapper.selectById(userId);
                if (user == null) {
                    Map<String, Object> error = new HashMap<>();
                    error.put("userId", userId);
                    error.put("reason", "用户不存在");
                    failureList.add(error);
                    continue;
                }

                // 查询报名记录
                QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("user_id", userId);
                queryWrapper.eq("lecture_id", lectureId);
                
                LectureRegistration registration = lectureRegistrationMapper.selectOne(queryWrapper);
                if (registration == null) {
                    Map<String, Object> error = new HashMap<>();
                    error.put("userId", userId);
                    error.put("username", user.getUsername());
                    error.put("reason", "未找到报名记录");
                    failureList.add(error);
                    continue;
                }

                if (registration.getRegistrationStatus() == 2) {
                    Map<String, Object> error = new HashMap<>();
                    error.put("userId", userId);
                    error.put("username", user.getUsername());
                    error.put("reason", "报名已取消");
                    failureList.add(error);
                    continue;
                }

                if (registration.getRegistrationStatus() == 1) {
                    Map<String, Object> error = new HashMap<>();
                    error.put("userId", userId);
                    error.put("username", user.getUsername());
                    error.put("reason", "已签到");
                    failureList.add(error);
                    continue;
                }

                // 执行签到
                registration.setRegistrationStatus(1);
                registration.setSignTime(new Date());
                
                int update = lectureRegistrationMapper.updateById(registration);
                if (update > 0) {
                    successList.add(user.getUsername());
                    successCount++;
                } else {
                    Map<String, Object> error = new HashMap<>();
                    error.put("userId", userId);
                    error.put("username", user.getUsername());
                    error.put("reason", "数据库更新失败");
                    failureList.add(error);
                }

            } catch (Exception e) {
                Map<String, Object> error = new HashMap<>();
                error.put("userId", userId);
                error.put("reason", e.getMessage());
                failureList.add(error);
            }
        }

        // 记录批量操作日志
        operationLogService.recordLog(
            operatorId,
            lectureId,
            4, // 实体类型：4-讲座
            String.format("管理员批量签到讲座[%s]，成功：%d人，失败：%d人",
                         lecture.getTitle(), successCount, failureList.size())
        );

        Map<String, Object> result = new HashMap<>();
        result.put("totalCount", userIds.size());
        result.put("successCount", successCount);
        result.put("failureCount", failureList.size());
        result.put("successList", successList);
        result.put("failureList", failureList);

        return result;
    }

    @Override
    public boolean cancelCheckIn(Long userId, Long lectureId, Long operatorId, String reason) {
        if (userId == null || lectureId == null || operatorId == null) {
            throw new BusinessException("用户ID、讲座ID和操作人ID不能为空");
        }

        // 检查操作人权限
        User operator = userMapper.selectById(operatorId);
        if (operator == null || operator.getRole() == null || operator.getRole() > 2) {
            throw new BusinessException("无权限执行此操作");
        }

        // 检查目标用户
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查讲座
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 查询报名记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("lecture_id", lectureId);
        
        LectureRegistration registration = lectureRegistrationMapper.selectOne(queryWrapper);
        if (registration == null) {
            throw new BusinessException("未找到报名记录");
        }

        if (registration.getRegistrationStatus() != 1) {
            throw new BusinessException("用户未签到，无法取消签到");
        }

        // 取消签到：将状态改回待签到，清空签到时间
        registration.setRegistrationStatus(0);
        registration.setSignTime(null);

        int update = lectureRegistrationMapper.updateById(registration);
        if (update <= 0) {
            throw new BusinessException("取消签到失败");
        }

        // 记录操作日志
        String logMessage = String.format("管理员[%s]取消用户[%s]的讲座签到：%s", 
                                          operator.getUsername(), user.getUsername(), lecture.getTitle());
        if (reason != null && !reason.trim().isEmpty()) {
            logMessage += "，原因：" + reason;
        }
        
        operationLogService.recordLog(
            operatorId,
            lectureId,
            4, // 实体类型：4-讲座
            logMessage
        );

        return true;
    }

    @Override
    public List<Map<String, Object>> getLectureCheckInList(Long lectureId) {
        if (lectureId == null) {
            throw new BusinessException("讲座ID不能为空");
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 查询已签到的报名记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lecture_id", lectureId);
        queryWrapper.eq("registration_status", 1); // 已签到
        queryWrapper.orderByAsc("sign_time");
        
        List<LectureRegistration> registrations = lectureRegistrationMapper.selectList(queryWrapper);
        
        // 组装返回数据
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<Map<String, Object>> result = registrations.stream()
                .map(registration -> {
                    Map<String, Object> item = new HashMap<>();
                    
                    // 获取用户信息
                    User user = userMapper.selectById(registration.getUserId());
                    
                    item.put("registrationId", registration.getId());
                    item.put("userId", registration.getUserId());
                    item.put("username", user != null ? user.getUsername() : "用户已删除");
                    item.put("email", user != null ? user.getEmail() : "");
                    item.put("registeredTime", registration.getRegisteredTime() != null ? sdf.format(registration.getRegisteredTime()) : null);
                    item.put("signTime", registration.getSignTime() != null ? sdf.format(registration.getSignTime()) : null);
                    item.put("registrationStatus", registration.getRegistrationStatus());
                    item.put("registrationStatusText", "已签到");
                    
                    return item;
                })
                .toList();
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getLectureNotCheckInList(Long lectureId) {
        if (lectureId == null) {
            throw new BusinessException("讲座ID不能为空");
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 查询未签到的报名记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lecture_id", lectureId);
        queryWrapper.eq("registration_status", 0); // 待签到
        queryWrapper.orderByAsc("registered_time");
        
        List<LectureRegistration> registrations = lectureRegistrationMapper.selectList(queryWrapper);
        
        // 组装返回数据
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<Map<String, Object>> result = registrations.stream()
                .map(registration -> {
                    Map<String, Object> item = new HashMap<>();
                    
                    // 获取用户信息
                    User user = userMapper.selectById(registration.getUserId());
                    
                    item.put("registrationId", registration.getId());
                    item.put("userId", registration.getUserId());
                    item.put("username", user != null ? user.getUsername() : "用户已删除");
                    item.put("email", user != null ? user.getEmail() : "");
                    item.put("registeredTime", registration.getRegisteredTime() != null ? sdf.format(registration.getRegisteredTime()) : null);
                    item.put("signTime", null);
                    item.put("registrationStatus", registration.getRegistrationStatus());
                    item.put("registrationStatusText", "待签到");
                    
                    return item;
                })
                .toList();
        
        return result;
    }

    @Override
    public Map<String, Object> checkSignInEligibility(Long userId, Long lectureId) {
        if (userId == null || lectureId == null) {
            throw new BusinessException("用户ID和讲座ID不能为空");
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Map<String, Object> result = new HashMap<>();
        result.put("canSignIn", false);
        result.put("message", "");

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            result.put("message", "用户不存在");
            return result;
        }

        // 检查讲座是否存在
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            result.put("message", "讲座不存在");
            return result;
        }

        // 检查讲座状态
        if (lecture.getLectureStatus() == 3) {
            result.put("message", "该讲座已取消");
            return result;
        }

        // 检查签到时间窗口
        Date now = new Date();
        long thirtyMinutes = 30 * 60 * 1000;
        long fifteenMinutes = 15 * 60 * 1000;
        
        Date checkInStartTime = new Date(lecture.getStartTime().getTime() - thirtyMinutes);
        Date checkInEndTime = new Date(lecture.getEndTime().getTime() + fifteenMinutes);
        
        if (now.before(checkInStartTime)) {
            result.put("message", "签到时间未到，请在讲座开始前30分钟内签到");
            result.put("checkInStartTime", sdf.format(checkInStartTime));
            return result;
        }
        if (now.after(checkInEndTime)) {
            result.put("message", "签到时间已过");
            result.put("checkInEndTime", sdf.format(checkInEndTime));
            return result;
        }

        // 查询报名记录
        QueryWrapper<LectureRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("lecture_id", lectureId);
        
        LectureRegistration registration = lectureRegistrationMapper.selectOne(queryWrapper);
        if (registration == null) {
            result.put("message", "未找到报名记录，请先报名");
            return result;
        }

        if (registration.getRegistrationStatus() == 2) {
            result.put("message", "报名已取消");
            return result;
        }
        if (registration.getRegistrationStatus() == 1) {
            result.put("message", "您已签到");
            result.put("signTime", registration.getSignTime() != null ? sdf.format(registration.getSignTime()) : null);
            return result;
        }

        // 可以签到
        result.put("canSignIn", true);
        result.put("message", "可以签到");
        result.put("lectureTitle", lecture.getTitle());
        result.put("lectureStartTime", sdf.format(lecture.getStartTime()));
        result.put("checkInStartTime", sdf.format(checkInStartTime));
        result.put("checkInEndTime", sdf.format(checkInEndTime));
        
        return result;
    }

    @Override
    public Result getLecturesByRoomId(Long roomId) {
        if (roomId == null) {
            throw new BusinessException(400, "房间ID不能为空");
        }
        // 房间不存在
        Room room = roomMapper.selectById(roomId);
        if (room == null) {
            throw new BusinessException(400, "房间不存在");
        }
        // 查询讲座，过滤已结束的讲座
        QueryWrapper<Lecture> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("classroom_id", roomId);
        queryWrapper.ne("lecture_status", 2); // 排除已结束的讲座
        List<Lecture> lectures = lectureMapper.selectList(queryWrapper);
        return Result.success(Map.of("lectures", lectures));
    }

    @Override
    public com.example.vo.LectureVO getLectureWithDetails(Long lectureId, Long userId) {
        if (lectureId == null) {
            throw new BusinessException("讲座ID不能为空");
        }

        // 获取讲座基本信息
        Lecture lecture = lectureMapper.selectById(lectureId);
        if (lecture == null) {
            throw new BusinessException("讲座不存在");
        }

        // 创建LectureVO并复制基本信息
        com.example.vo.LectureVO lectureVO = new com.example.vo.LectureVO();
        org.springframework.beans.BeanUtils.copyProperties(lecture, lectureVO);

        // 获取教室和图书馆信息
        if (lecture.getClassroomId() != null) {
            Room room = roomMapper.selectById(lecture.getClassroomId());
            if (room != null) {
                lectureVO.setLibraryId(room.getLibraryId());
                lectureVO.setClassroomName(room.getName());
                
                // 获取图书馆名称
                if (room.getLibraryId() != null) {
                    com.example.domain.Library library = libraryMapper.selectById(room.getLibraryId());
                    if (library != null) {
                        lectureVO.setLibraryName(library.getName());
                    }
                }
            }
        }

        // 获取报名统计信息
        QueryWrapper<LectureRegistration> countWrapper = new QueryWrapper<>();
        countWrapper.eq("lecture_id", lectureId);
        countWrapper.ne("registration_status", 2); // 排除已取消的
        long currentRegistrations = lectureRegistrationMapper.selectCount(countWrapper);
        lectureVO.setCurrentRegistrations(currentRegistrations);

        // 计算剩余名额
        if (lecture.getParticipantLimit() != null && lecture.getParticipantLimit() > 0) {
            int availableSlots = Math.max(0, (int)(lecture.getParticipantLimit() - currentRegistrations));
            lectureVO.setAvailableSlots(availableSlots);
            lectureVO.setIsFull(availableSlots == 0);
        } else {
            lectureVO.setAvailableSlots(-1); // 无限制
            lectureVO.setIsFull(false);
        }

        // 如果提供了用户ID，获取用户报名状态
        if (userId != null) {
            QueryWrapper<LectureRegistration> userRegWrapper = new QueryWrapper<>();
            userRegWrapper.eq("user_id", userId);
            userRegWrapper.eq("lecture_id", lectureId);
            
            LectureRegistration registration = lectureRegistrationMapper.selectOne(userRegWrapper);
            if (registration != null) {
                lectureVO.setRegistrationId(registration.getId());
                lectureVO.setRegistrationStatus(registration.getRegistrationStatus());
                lectureVO.setHasRegistered(registration.getRegistrationStatus() != 2);
            } else {
                lectureVO.setRegistrationId(null);
                lectureVO.setRegistrationStatus(null);
                lectureVO.setHasRegistered(false);
            }
        }

        return lectureVO;
    }

    @Override
    public List<com.example.vo.LectureVO> listAllLecturesWithDetails(Long userId) {
        // 过滤已结束的讲座（状态为2）
        QueryWrapper<Lecture> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("lecture_status", 2); // 排除已结束的讲座
        List<Lecture> lectures = lectureMapper.selectList(queryWrapper);
        return lectures.stream()
                .map(lecture -> getLectureWithDetails(lecture.getId(), userId))
                .toList();
    }
}